package jehc.cloud.iot.live.common.util;

import jehc.cloud.iot.live.model.CameraEntity;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
 * @Desc 截图工具类
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Component
@Slf4j
public class ScreenShotUtil {


    /**
     * 获取指定视频的帧并保存为图片至指定目录
     * @param cameraEntity
     * @throws Exception
     * @throws IOException
     */
    public Boolean fetchFrame(CameraEntity cameraEntity){
        Boolean res = true;
        FFmpegFrameGrabber fFmpegFrameGrabber = null;
        try {
            String videofile = cameraEntity.getRtspUrl();//源视频文件路径
            log.info("截屏输入路径："+videofile);
            String outfile = cameraEntity.getPath()+"/"+cameraEntity.getVideoName()+"."+cameraEntity.getImageType();//截取帧的图片存放路径
            log.info("截屏输出路径："+outfile);
            fFmpegFrameGrabber = FFmpegFrameGrabber.createDefault(videofile);
            /*fFmpegFrameGrabber = new FFmpegFrameGrabber(videofile);*/
            fFmpegFrameGrabber.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);//设置帧收集时的像素格式，默认使用AV_PIX_FMT_YUV420P，（注意：这块设置avutil.AV_PIX_FMT_RGBA的原因主要是，我们展示画面的时候是转换为Bitmap格式的。）
            fFmpegFrameGrabber.setVideoCodec(avcodec.AV_CODEC_ID_H264);// h264编/解码器
            fFmpegFrameGrabber.setVideoOption("vcodec", "copy");
            // 微秒 大概为设置时间的两倍
            fFmpegFrameGrabber.setOption("stimeout", "2000000");//设置采集器构造超时时间2000000微秒=2秒
            // rtsp 默认udp 丢包 改为tcp
            fFmpegFrameGrabber.setOption("rtsp_transport", "tcp");
            fFmpegFrameGrabber.start();
            log.info("ImageWidth:" + fFmpegFrameGrabber.getImageWidth());
            log.info("ImageHeight:" + fFmpegFrameGrabber.getImageHeight());
            log.info("AudioChannels:" + fFmpegFrameGrabber.getAudioChannels());
            log.info("Format:" + fFmpegFrameGrabber.getFormat());
            Frame f;
            if(null != fFmpegFrameGrabber){
                fFmpegFrameGrabber.flush();// 释放探测时缓存下来的数据帧，避免pts初始值不为0导致画面延时
            }
            //跳转到需要截图到那一帧
            int totalFrames = fFmpegFrameGrabber.getLengthInFrames();
            log.info("总帧数:" + totalFrames);
            /* 废弃取帧
            fFmpegFrameGrabber.setFrameNumber(cameraEntity.getFrame());//要截取指定一帧
            fFmpegFrameGrabber.setFrameNumber(totalFrames-1);//要截取倒数第二帧
            */
            f = fFmpegFrameGrabber.grabImage();
            doExecuteFrame(f,outfile,cameraEntity.getImageType());
            if(null != fFmpegFrameGrabber){
                fFmpegFrameGrabber.stop();
                log.info("关闭fFmpegFrameGrabber成功");
            }
        }catch (Exception e){
            res = false;
            log.error("截图出现异常：{}",e);

        }finally {
            try {
                if(null != fFmpegFrameGrabber){
                    fFmpegFrameGrabber.stop();
                    log.info("关闭fFmpegFrameGrabber成功");
                }
            }catch (Exception e){

            }
        }
        return res;
    }



    /**
     * 处理导出图片
     * @param f
     * @param outPathFile 输出文件
     * @param imageType 图片类型
     */
    public  void doExecuteFrame(Frame f, String outPathFile,String imageType) {
        if (null == f || null == f.image) {
            return;
        }
        Java2DFrameConverter converter = new Java2DFrameConverter();
        BufferedImage bi = converter.getBufferedImage(f);
        File output = new File(outPathFile);
        try {
            ImageIO.write(bi, imageType, output);
        } catch (IOException e) {
            log.error("导出图片异常：{}",e);
        }
    }
}
